package com.custom.base.manager

import android.os.Bundle
import android.util.Log

import androidx.fragment.app.Fragment
import androidx.fragment.app.FragmentActivity
import androidx.fragment.app.FragmentManager
import androidx.fragment.app.FragmentTransaction

/**
 * 作者：
 * 时间：12/10/20
 * 描述：
 */
class SDFragmentManager(private val mManager: FragmentManager) {
    private var mFragmentLastToggle: Fragment? = null

    fun getmFragmentLastToggle(): Fragment? {
        return mFragmentLastToggle
    }

    fun beginTransaction(): FragmentTransaction {
        return mManager.beginTransaction()
    }

    fun findFragmentByTag(tag: String): Fragment? {
        return mManager.findFragmentByTag(tag)
    }

    fun findFragmentById(id: Int): Fragment? {
        return mManager.findFragmentById(id)
    }

    fun remove(vararg fragments: Fragment): SDFragmentManager {
        if (fragments != null && fragments.size > 0) {
            val transaction = beginTransaction()
            var fragment: Fragment? = null
            for (i in fragments.indices) {
                fragment = fragments[i]
                if (fragment != null) {
                    transaction.remove(fragment)
                    transaction.commitNow()
                }
            }
        }
        return this
    }

    fun show(vararg fragments: Fragment): SDFragmentManager {
        if (fragments != null && fragments.size > 0) {
            val transaction = beginTransaction()
            var fragment: Fragment? = null
            for (i in fragments.indices) {
                fragment = fragments[i]
                if (fragment != null) {
                    transaction.show(fragment)
                }
            }
            transaction.commitAllowingStateLoss()
        }
        return this
    }

    fun hide(vararg fragments: Fragment): SDFragmentManager {
        if (fragments != null && fragments.size > 0) {
            val transaction = beginTransaction()
            var fragment: Fragment? = null
            for (i in fragments.indices) {
                fragment = fragments[i]
                if (fragment != null) {
                    transaction.hide(fragment)
                }
            }
            transaction.commitAllowingStateLoss()
        }
        return this
    }

    @JvmOverloads
    fun replace(
        container: Int,
        fragmentClazz: Class<out Fragment>,
        args: Bundle? = null,
        addToBackStack: Boolean = false
    ): Fragment? {
        return replace(container,
            newFragment(fragmentClazz), args, addToBackStack)
    }

    @JvmOverloads
    fun replace(
        container: Int,
        fragment: Fragment?,
        args: Bundle? = null,
        addToBackStack: Boolean = false
    ): Fragment? {
        if (fragment != null) {
            putFragmentData(fragment, args)
            val transaction = beginTransaction()
            val tag = fragment.javaClass.simpleName

            transaction.replace(container, fragment, tag)

            if (addToBackStack) {
                transaction.addToBackStack(null)
            }
            transaction.commitAllowingStateLoss()

        }
        return fragment
    }

    @JvmOverloads
    fun add(
        container: Int,
        fragmentClazz: Class<out Fragment>,
        args: Bundle? = null,
        addToBackStack: Boolean = false
    ): Fragment? {
        return add(container,
            newFragment(fragmentClazz), args, addToBackStack)
    }

    @JvmOverloads
    fun add(
        container: Int,
        fragment: Fragment?,
        args: Bundle? = null,
        addToBackStack: Boolean = false
    ): Fragment? {
        if (fragment != null) {
            putFragmentData(fragment, args)
            val transaction = beginTransaction()
            val tag = fragment.javaClass.simpleName

            transaction.add(container, fragment, tag)

            if (addToBackStack) {
                transaction.addToBackStack(null)
            }
            transaction.commitAllowingStateLoss()
        }
        return fragment
    }

    @JvmOverloads
    fun toggle(
        container: Int,
        showFragment: Fragment,
    ): Fragment {
        val tag = showFragment.tag
        val transaction = beginTransaction()
        if (!showFragment.isAdded) {
            if (mFragmentLastToggle != null) {
                transaction.hide(mFragmentLastToggle!!)
                    .add(container, showFragment, tag)
                    .commitNow()
            } else {
                transaction.add(container, showFragment, tag)
                        .commitNow()
            }
        }else{
            mFragmentLastToggle?.let {
                transaction.hide(it).show(showFragment).commitNow()
            }
        }
        mFragmentLastToggle = showFragment
        return showFragment
    }


    companion object {

        fun putFragmentData(fragment: Fragment?, args: Bundle?) {
            if (fragment != null) {
                if (args != null && !args.isEmpty) {
                    val bundle = fragment.arguments
                    if (bundle != null) {
                        bundle.putAll(args)
                    } else {
                        fragment.arguments = args
                    }
                }
            }
        }

        fun newFragment(clazz: Class<out Fragment>): Fragment? {
            var fragment: Fragment? = null
            try {
                fragment = clazz.newInstance()
            } catch (e: InstantiationException) {
                e.printStackTrace()
            } catch (e: IllegalAccessException) {
                e.printStackTrace()
            }

            return fragment
        }
    }
}
